#include "wavefrontmesh.h"

WaveFrontMesh::WaveFrontMesh(  ) 
{
	// TODO
}

int WaveFrontMesh::read(FILE *f, int (*updateProgress)(int pos),
		  void (*setTotal)(int size))
{
  QList<Triangle*> *shapeTriangles;
  QList<Vertex*> *shapeVertices;
  QVector<Vertex*> vertexIndex;
  QVector<int> faceIndices;
  Triangle *tri;
  Vertex *v;
  char type;
  int p;
  float x, y, z;
	
  fseek(f, 0, SEEK_END);
  (*setTotal)(ftell(f));
  fseek(f, 0, SEEK_SET);

  shapeTriangles = new QList<Triangle*>;
  shapeVertices = new QList<Vertex*>;

  while ((type=fgetc(f)) != EOF)
  {
    switch (type)
      {
	case '#': // Comment
	  do    // Reads till end of the line
	    {
	      type=fgetc(f);
	    }
	  while (type != EOF && type != '\n');
	  break;

	case 'v': // Vertex
		
	  // check it is a vertex of "v" and not "vt" or "vn"
	
	  type=fgetc(f); 
	  if (type == ' '){
	    if (fscanf(f,"%f %f %f\n",&x,&y,&z) != 3)
	      {
		//FILE_ERROR(f, "OBJ file format error: v");
		return 1;
	      }
		
	    v = new Vertex(x,y,z);
	    addVertex(v);
		
	    // save in a vector for the triangles and shape
	    vertexIndex.push_back(v);
	  }
	  break;

	case 'f': // Polygon with n vertices
	
	  faceIndices.clear();

	  // read vertex indices of the current face until end of line

	  do
	  {
	    if (fscanf(f," %d", &p) != 1)
	      break;

	    faceIndices.push_back(p);

	    do    // Reads till next space
	      { type=fgetc(f); }
	    while (type != EOF && type != ' ' && type != '\n');
	  }
	  while (type != '\n');

	  // build normal triangle

	  if (faceIndices.size() == 3)
	  {
	    if (faceIndices[0] < 1 || faceIndices[1] < 1 || faceIndices[2] < 1 ||
		faceIndices[0] > vertNr || faceIndices[1] > vertNr || faceIndices[2] > vertNr)
	    {
	      //FILE_ERROR(f, "OBJ file format error: wrong vertex index");
	      return 2;
	    }
		
	    tri = new Triangle(vertexIndex[ faceIndices[0]-1 ], vertexIndex[ faceIndices[1]-1 ], 
			       vertexIndex[ faceIndices[2]-1 ] );
		
	    addTriangle(tri);
	    shapeTriangles->push_back(tri);

	  }

	  // build triangles from polygons

	  if (faceIndices.size() > 3)
	  {
	    for (p=1; p < faceIndices.size()-1; p++)
	    {
	      if (faceIndices[0] < 1 || faceIndices[p] < 1 || faceIndices[p+1] < 1 ||
		  faceIndices[0] > vertNr || faceIndices[p] > vertNr || faceIndices[p+1] > vertNr)
	      {
	      	//FILE_ERROR(f, "OBJ file format error: wrong vertex index");
			return 2;
	      }

	      tri = new Triangle(vertexIndex[ faceIndices[0]-1 ], vertexIndex[ faceIndices[p]-1 ],
				 vertexIndex[ faceIndices[p+1]-1 ], POLYGON_TRIANGLE);
	      addTriangle(tri);
	      shapeTriangles->push_back(tri);

	    }
	  }

	  break;

	default:
	  // skip lines starting with all all other chars	
 		
	  do    // Reads till end of the line
	    {
	      type=fgetc(f);
	    }
	  while (type != EOF && type != '\n');
	  break;
      }

    if ((*updateProgress)(ftell(f)))
      return 90;
  }

  // copy the vertices of this shape over
  /*
  shapeVertices->insert(shapeVertices->begin(), 
			vertexIndex.begin(), vertexIndex.end());

  shapes->push_back(new Shape(shapeTriangles, shapeVertices));
  */
  return 0;
}
